import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.*;
import javax.swing.BoxLayout;
import javax.swing.JTabbedPane;

public class RootPanel extends Panel implements Tickable {   
    private Timer tickTimer;

    private VariableControl varCtrl;
    private Core carDisplay;

    // Side panels
    private Panel defaultSidePanel;
    private FunctionDisplay functionDisplay;
    private JTabbedPane sidePanelTabs;
    
    
    // Graph display
    private GraphOwner graphs;
    
    public RootPanel(String label) {
        this.varCtrl = new VariableControl("variables");     
        this.carDisplay = new Core("cars", varCtrl);     
        this.graphs = new GraphOwner( this.carDisplay );
        this.functionDisplay = new FunctionDisplay(this);
        
        this.varCtrl.addPropertyChangeListener(new VarChangeListener());
        
        this.estabishLayout();
        this.setupTimer();

        // TODO: remove background setting. This is to help with layout
        this.carDisplay.setBackground( Color.black );
    }
    
    private void estabishLayout() {
    	this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
    
    	this.defaultSidePanel = new Panel (); 
    	this.defaultSidePanel.setLayout(new BoxLayout(this.defaultSidePanel, BoxLayout.Y_AXIS));

    	this.defaultSidePanel.add("graph", this.graphs);  
    	this.defaultSidePanel.add("variables", this.varCtrl); 
    	this.defaultSidePanel.add("buttons", new ActionControl(this.carDisplay));
        
    	this.sidePanelTabs = new JTabbedPane();
    	this.sidePanelTabs.setBackground(Color.WHITE);
    	this.sidePanelTabs.addTab("Fuzzy Controls", this.defaultSidePanel);
    	this.sidePanelTabs.addTab("Fuzzy Membership Functions", this.functionDisplay);
    	
        this.add("cars", this.carDisplay);   
        this.add(this.sidePanelTabs);
    }
    
    private void setupTimer() {
        tickTimer = new Timer();
        int delay = 0;
        int framerate = 250;

        tickTimer.scheduleAtFixedRate(
            new TickTimerTask(this), delay, framerate
        );

    }
    
    public Core GetCarDisplay() {
    	return this.carDisplay;
    }
    
    public void tick() {
        if ( !this.carDisplay.getPaused() ) {
            // tick output
            carDisplay.tick();
            graphs.tick();
        }
    }

    private class TickTimerTask extends java.util.TimerTask {
        private Tickable toTick;
        public TickTimerTask(Tickable toTick) {
            this.toTick = toTick;
        }
        public void run() {
            toTick.tick();
        }
    }
    
    private class VarChangeListener implements PropertyChangeListener {
		public void propertyChange(PropertyChangeEvent evt) {
			functionDisplay.refreshGraphs();
		}
    }
}
